package note;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class DesktopNoteApp extends JDialog {

    private List<String> notes = new ArrayList<>();
    private JTextArea noteTextArea;
    private Point initialClick;
    private Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();// 获取屏幕的大小
    // 当前内容，当窗口被隐藏时，记录文本域的当前内容，当窗口再次显示，将内容重新赋值给文本域
    private String currentContent = "";

    // 默认的窗口透明度，分别是便签窗口和历史记录窗口
    private float opacity1 = 0.5f, opacity2 = 0.5f;
    // 默认的字体大小，分别是便签窗口和历史记录窗口
    private int fontSize1 = 14, fontSize2 = 14;
    // 默认的图标弹窗的图标路径
    // private String iconDialogPath = "java-tools/src/main/java/note/trayIcon.png";
    private String iconDialogPath = "java-tools/src/main/java/note/timo.jpg";


    public DesktopNoteApp() {
        loadNotes();// 先加载txt文件
        setUndecorated(true);// 去掉外面的边框修饰。
        setResizable(false);
        setLayout(new BorderLayout());
        setSize(300, 300);
        setPreferredSize(new Dimension(300, 300));
        setOpacity(opacity1);
        pack();

        // 标题栏面板
        JPanel titleBar = new JPanel();
        titleBar.setBackground(Color.decode("#6c768a"));
        titleBar.setLayout(new BorderLayout());

        JLabel titleLabel = new JLabel("桌面便签");
        titleLabel.setForeground(Color.WHITE);
        titleLabel.setHorizontalAlignment(SwingConstants.CENTER);
        titleBar.add(titleLabel, BorderLayout.NORTH);
        titleLabel.setPreferredSize(new Dimension(300, 30));

        // 鼠标动作监听器
        titleBar.addMouseMotionListener(new MouseAdapter() {
            // 鼠标拖动
            public void mouseDragged(MouseEvent e) {
                int thisX = getLocation().x;
                int thisY = getLocation().y;
                int xMoved = e.getX() - initialClick.x;
                int yMoved = e.getY() - initialClick.y;
                int x = thisX + xMoved;
                int y = thisY + yMoved;
                setLocation(x, y);
            }
        });
        // 当标题栏面板右键时，弹出菜单
        JPopupMenu popupMenu = popupMenu();
        // 鼠标监听事件
        titleBar.addMouseListener(new MouseAdapter() {
            // 鼠标按下
            public void mousePressed(MouseEvent e) {
                initialClick = e.getPoint();
                getComponentAt(initialClick);
                if (e.isPopupTrigger()) {
                    popupMenu.show(e.getComponent(), e.getX(), e.getY());
                }
                if (e.getClickCount() == 2) { // 鼠标双击
                    currentContent = noteTextArea.getText();
                    setVisible(false);// 隐藏便签窗口
                    iconDialog();// 显示图标
                }
            }

            // 鼠标松开
            public void mouseReleased(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    popupMenu.show(e.getComponent(), e.getX(), e.getY());
                }
            }
        });
        add(titleBar, BorderLayout.NORTH);

        // 文本域
        noteTextArea = new JTextArea();
        noteTextArea.setLineWrap(true);
        noteTextArea.setFont(new Font("微软雅黑", Font.PLAIN, fontSize1));
        noteTextArea.setMargin(new Insets(10, 20, 10, 20));
        noteTextArea.addMouseListener(new MouseAdapter() {
            // 鼠标双击
            public void mousePressed(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    currentContent = noteTextArea.getText();
                    setVisible(false);// 隐藏便签窗口
                    iconDialog();// 显示图标
                }
            }
        });

        // 文本域的滚动条
        JScrollPane scrollPane = new JScrollPane(noteTextArea);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        add(scrollPane, BorderLayout.CENTER);

        // 下方的按钮面板
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));

        buttonPanel.add(newButton()); // 新增按钮和它的事件
        buttonPanel.add(historyButton()); // 查看历史按钮和它的事件
        buttonPanel.add(clearButton()); // 清空所有便签内容按钮和它的事件
        buttonPanel.add(deleteButton()); // 删除所有历史便签内容和它的事件

        add(buttonPanel, BorderLayout.SOUTH);

        // 贴边隐藏窗口
        /*addComponentListener(new ComponentAdapter() {
            @Override
            public void componentMoved(ComponentEvent e) {
                int x = getLocation().x;
                int y = getLocation().y;
                int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
                int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
                if (x <= 0 || y <= 0 || x + getWidth() >= screenWidth || y + getHeight() >= screenHeight) {
                    setVisible(false);// 隐藏便签窗口
                    iconDialog();// 显示图标
                }
            }
        });*/

        pack();
        // 设置对话框的位置，位于屏幕右上角位置
        int x = screenSize.width - getWidth();
        setLocation(x - 50, 50);
        setAlwaysOnTop(true);// 置于顶层，不会受win+d影响
        if (SystemTray.isSupported()) {
            addTrayIcon();
        }
        setVisible(true);
    }

    /**
     * 右键标题栏，弹出菜单
     */
    private JPopupMenu popupMenu() {
        JPopupMenu popupMenu = new JPopupMenu();
        // 关闭菜单
        JMenuItem closeMenuItem = new JMenuItem("退出");
        closeMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                dispose();// 释放窗口
                System.exit(0);// 关闭程序
            }
        });
        popupMenu.add(closeMenuItem);
        return popupMenu;
    }

    /**
     * 新增按钮和它的事件
     */
    private JButton newButton() {
        JButton newButton = new JButton("新增");
        newButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String note = noteTextArea.getText();
                if (note.length() > 0) {
                    Date date = new Date();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String format = sdf.format(date);
                    note = format + "：" + note;
                    notes.add(note);
                    saveNotes();
                    noteTextArea.setText("");
                    currentContent = "";
                }
            }
        });
        return newButton;
    }

    /**
     * 查看历史按钮和它的事件和它的事件
     */
    private JButton historyButton() {
        JButton historyButton = new JButton("历史");
        historyButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                historyDialog();// 创建一个JDialog模态框
            }
        });
        return historyButton;
    }

    /**
     * 清空当前面板内容按钮和它的事件
     */
    private JButton clearButton() {
        JButton clearButton = new JButton("清空");
        clearButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String msg = "是否要清空当前面板内容？\n\n清空后将不保存到历史记录中。";
                createConfirm("清空当前内容", msg, 1);
            }
        });
        return clearButton;
    }

    /**
     * 删除所有历史便签内容和它的事件
     */
    private JButton deleteButton() {
        JButton deleteButton = new JButton("删除");
        deleteButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String msg = "是否要删除所有便签内容？\n\n其中包括历史记录内容。";
                createConfirm("删除所有内容，包括历史记录", msg, 2);
            }
        });
        return deleteButton;
    }

    /**
     * 创建一个是或否的对话框
     *
     * @param title 对话框title
     * @param msg   对话框提示信息
     * @param type  1 清空当前对话框内容 2 清空当前对话框内容以及删除历史记录
     */
    private void createConfirm(String title, String msg, int type) {
        JDialog dialog = new JDialog();
        dialog.setTitle(title);
        dialog.setModal(true);
        dialog.setAlwaysOnTop(true);// 历史模态框置顶
        JOptionPane optionPane = new JOptionPane(msg, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION);
        dialog.setContentPane(optionPane);
        optionPane.addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                String prop = evt.getPropertyName();
                if (dialog.isVisible() && (evt.getSource() == optionPane) && (prop.equals(JOptionPane.VALUE_PROPERTY))) {
                    int result = (Integer) optionPane.getValue();
                    if (result == JOptionPane.YES_OPTION) { // 执行清空操作
                        noteTextArea.setText("");
                        if (type == 2) {
                            notes.clear();
                            clearNotes();
                        }
                    }
                    dialog.dispose(); // 关闭对话框
                }
            }
        });
        int x = screenSize.width - getWidth();
        dialog.setLocation(x - 50, 100);
        dialog.pack();
        dialog.setVisible(true);
    }

    /**
     * 添加系统托盘
     * 托盘图标为什么悬停才会显示 图片太透明了
     * java swing实现窗口最小化到托盘，点击托盘图标显示原窗口 https://blog.51cto.com/u_15166912/2706010
     */
    private void addTrayIcon() {
        SystemTray tray = SystemTray.getSystemTray();
        // Image image = Toolkit.getDefaultToolkit().getImage("trayIcon.png");
        Image image = Toolkit.getDefaultToolkit().getImage(iconDialogPath);
        PopupMenu menu = new PopupMenu();
        MenuItem exitMenuItem = new MenuItem("exit");
        exitMenuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        menu.add(exitMenuItem);

        TrayIcon trayIcon = new TrayIcon(image, "桌面便签", menu);
        trayIcon.setImageAutoSize(true);

        try {
            tray.add(trayIcon);
        } catch (AWTException e) {
            e.printStackTrace();
        }
    }

    /**
     * 历史记录弹框
     */
    private void historyDialog() {
        JDialog historyDialog = new JDialog();
        // 创建一个JDialog模态框
        historyDialog.setUndecorated(true);
        historyDialog.setOpacity(opacity2);// 这个要设置setUndecorated(true)才起作用
        historyDialog.setTitle("便签历史");
        historyDialog.setModal(true);// 设置为模态对话框，这样就不允许与其他窗口交互，只能先关闭这个窗口才能操作其他窗口
        historyDialog.setResizable(false);
        historyDialog.setLayout(new BorderLayout());
        historyDialog.setSize(400, 300);
        historyDialog.setPreferredSize(new Dimension(400, 300));
        // 显示历史内容的文本域
        JTextArea historyTextArea = new JTextArea();
        historyTextArea.setEditable(false);
        historyTextArea.setFont(new Font("微软雅黑", Font.PLAIN, fontSize2));
        historyTextArea.setMargin(new Insets(15, 15, 15, 15));
        // 文本域的滚动条
        JScrollPane scrollPane = new JScrollPane(historyTextArea);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        historyDialog.add(scrollPane, BorderLayout.CENTER);
        // 读取历史内容并设置到文本域中
        StringBuilder history = new StringBuilder();
        for (String note : notes) {
            history.append(note).append("\n\n");
        }
        historyTextArea.setText(history.toString());

        // 鼠标动作监听器
        historyTextArea.addMouseMotionListener(new MouseAdapter() {
            // 鼠标拖动
            public void mouseDragged(MouseEvent e) {
                int thisX = historyDialog.getLocation().x;
                int thisY = historyDialog.getLocation().y;
                int xMoved = e.getX() - initialClick.x;
                int yMoved = e.getY() - initialClick.y;
                int x = thisX + xMoved;
                int y = thisY + yMoved;
                historyDialog.setLocation(x, y);
            }
        });

        historyTextArea.addMouseListener(new MouseAdapter() {
            // 鼠标双击隐藏
            public void mousePressed(MouseEvent e) {
                initialClick = e.getPoint();
                historyDialog.getComponentAt(initialClick);
                if (e.getClickCount() == 2) {
                    historyDialog.setVisible(false);
                }
            }
        });
        // 设置对话框的位置，位于屏幕右上角位置
        int x = screenSize.width - getWidth();
        historyDialog.setLocation(x - 50, 50);
        historyDialog.pack();
        historyDialog.setAlwaysOnTop(true);// 历史模态框置顶
        historyDialog.setVisible(true);
    }

    /**
     * 图标弹框
     */
    private void iconDialog() {
        JDialog iconDialog = new JDialog();
        ImageIcon icon = new ImageIcon(iconDialogPath);//图片的路径
        int iconWidth = icon.getIconWidth() / 2;
        int iconHeight = icon.getIconHeight() / 2;
        iconDialog.setUndecorated(true);// 去掉外面的边框修饰。
        iconDialog.setResizable(false);
        iconDialog.setBackground(new Color(0, 0, 0, 0));//背景透明
        iconDialog.setLayout(new BorderLayout());
        iconDialog.setSize(iconWidth, iconHeight);
        iconDialog.setPreferredSize(new Dimension(iconWidth, iconHeight));
        // 设置对话框的位置，位于屏幕右上角位置
        int x = screenSize.width - getWidth();
        iconDialog.setLocation(x + 150, 50);
        iconDialog.setAlwaysOnTop(true);// 置于顶层，不会受win+d影响

        //添加图片
        JLabel label = new JLabel();
        icon.setImage(icon.getImage().getScaledInstance(iconWidth, iconHeight, Image.SCALE_AREA_AVERAGING));
        label.setBounds(getX(), getY(), iconWidth, iconHeight);
        label.setSize(iconWidth, iconHeight);
        label.setIcon(icon);
        iconDialog.add(label);

        // 鼠标动作监听器
        iconDialog.addMouseMotionListener(new MouseAdapter() {
            // 鼠标拖动
            public void mouseDragged(MouseEvent e) {
                int thisX = iconDialog.getLocation().x;
                int thisY = iconDialog.getLocation().y;
                int xMoved = e.getX() - initialClick.x;
                int yMoved = e.getY() - initialClick.y;
                int x = thisX + xMoved;
                int y = thisY + yMoved;
                iconDialog.setLocation(x, y);
            }
        });
        iconDialog.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                initialClick = e.getPoint();
                iconDialog.getComponentAt(initialClick);
                if (e.getClickCount() == 2) {
                    iconDialog.setVisible(false);//隐藏图标窗口
                    noteTextArea.setText(currentContent);//设置文本域内容
                    setVisible(true);//显示便签窗口
                }
            }
        });
        iconDialog.setVisible(true);
    }

    /**
     * 加载保存的文件
     */
    private void loadNotes() {
        try {
            File file = new File("notes.txt");
            FileInputStream fis = null;
            InputStreamReader isr = null;
            BufferedReader reader = null;
            if (file.exists()) {
                fis = new FileInputStream(file);
                isr = new InputStreamReader(fis, "utf-8");
                reader = new BufferedReader(isr);
                String line;
                while ((line = reader.readLine()) != null) {
                    notes.add(line);
                }
                reader.close();
                isr.close();
                fis.close();
            }
            File setFile = new File("set.txt");
            if (setFile.exists()) {
                fis = new FileInputStream(setFile);
                isr = new InputStreamReader(fis, "utf-8");
                reader = new BufferedReader(isr);
                String line;
                while ((line = reader.readLine()) != null) {
                    if (line.length() > 0) {
                        String s = line.split("=")[1];
                        s = s.trim();
                        if (line.startsWith("便签窗口透明度")) opacity1 = (float) Double.parseDouble(s);
                        if (line.startsWith("历史窗口透明度")) opacity1 = (float) Double.parseDouble(s);
                        if (line.startsWith("便签窗口字体大小")) fontSize1 = Integer.parseInt(s);
                        if (line.startsWith("历史窗口字体大小")) fontSize2 = Integer.parseInt(s);
                        if (line.startsWith("图标弹窗图标路径")) iconDialogPath = s;
                    }
                }
                reader.close();
                isr.close();
                fis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将内容保存到txt文件中
     */
    private void saveNotes() {
        try {
            BufferedWriter writer = new BufferedWriter(new FileWriter("notes.txt"));
            for (String note : notes) {
                writer.write(note);
                writer.newLine();
            }
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将txt文件中的内容全部清空
     */
    private void clearNotes() {
        try {
            BufferedWriter writer = new BufferedWriter(new FileWriter("notes.txt"));
            writer.write("");
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new DesktopNoteApp();
            }
        });
    }
}

